# Copyright (c) 2009 Peter Houghton 
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.

# WATIR GRID

require 'rubygems'
require 'test/unit'
require 'yaml'
require File.expand_path(File.dirname(__FILE__) + "/../lib/watirgrid")
require 'net/http'
require 'uri'


class Grid_map_tests < Test::Unit::TestCase
  
    def setup
      @path = File.expand_path(File.dirname(__FILE__) + "/../test")
      @config_file_1= @path + "/" + "grid_servers_test1.yaml" # Single test server 
      @config_file_2= @path + "/" + "grid_servers_test2.yaml" # Missing Description field
      @config_file_3= @path + "/" + "grid_servers_test3.yaml" # 3 valid servers
      
    end # end setup
	  
	  def teardown
	    # no teardown
	  end # end teardown/clearup

    # Load servers from yaml file
    # The servers yaml file contains details of each server available to the grid
    # Each server has at a minimum: ip address, port, name/keyword.
    #
    def test_grid_map_load
      agridhub = WatirGrid::GridHub.new
      agridhub.load_server_config(@config_file_1)
      assert_equal(Hash.new.class , agridhub.servers.class , "Check servers returns a Hash")
      assert_equal(1 , agridhub.servers.length , "Check servers returns the correct number of server key arrays")
      watir_details = agridhub.servers.shift[1][0]
      assert_equal(WatirGrid::WatirServerDetail.new.class ,  watir_details.class , "Check returns array of WatirServerDetail objects")
      
      assert_equal(String.new.class , watir_details.to_yaml.class , "Check details can be to_yaml ed")      
      assert_equal(1 , YAML::load(watir_details.to_yaml).length , "Check details are just one server")
    end # end 

    # Test the loading of server details rom YAML Config file.
    # Check the correct fields are all loaded.
    #
    def test_grid_map_load_servers
      agridhub = WatirGrid::GridHub.new
      agridhub.load_server_config(@config_file_1)
      # First server entry
      assert_equal("local_vm1" , agridhub.servers.values[0][0].name , "Check server name")
      assert_equal(7777 , agridhub.servers.values[0][0].port , "Check server port")
      assert_equal("192.168.10.10" , agridhub.servers.values[0][0].address , "Check server ip")
      assert_equal("ie6_xp" , agridhub.servers.values[0][0].browser_key , "Check server key")
      assert_equal("Test Windows XP with IE6" , agridhub.servers.values[0][0].description , "Check description")
    
    end  # end
    
    # Test the serialising of the server details back to yaml
    # Check the correct fields are all serialised
    #
    def test_grid_map_serialise
      agridhub = WatirGrid::GridHub.new
      agridhub.load_server_config(@config_file_1)
      # First server entry, extract - to_yaml, then reload
      hashed_yaml = YAML::load(agridhub.servers.values[0][0].to_yaml)
      
      # Extract the single entry, name and details
      detail_array = hashed_yaml.shift
      name_loaded = detail_array[0]
      details_loaded = detail_array[1]
      
      assert_equal("local_vm1" ,name_loaded , "Check name")
      assert_equal("ie6_xp" , details_loaded["browser_key"] , "Check server key")
      assert_equal("Test Windows XP with IE6" , details_loaded["description"] , "Check description")
      assert_equal("192.168.10.10" , details_loaded["address"] , "Check server ip")

    end # end

    # Test that a YAML config file missing a field of data - causes an exception to be raised.
    #
    def test_grid_map_load_servers_missing_data
      agridhub = WatirGrid::GridHub.new
      assert_raises RuntimeError do
        agridhub.load_server_config(@config_file_2)   
      end # end assert
    end # end test
    
    # Test that servers are correctly setup up as unlocked.
    #
    def test_grid_map_free_servers
      agridhub = WatirGrid::GridHub.new
      agridhub.load_server_config(@config_file_3)
      assert_equal(2 , agridhub.free_servers("ie6_xp")  , "Check number of free servers is correct before locking")
      assert_equal(1 , agridhub.free_servers("ie7_xp")  , "Check number of free servers is correct before locking")
    end # end test
    
    # Check locking works when 'get_server'
    #
    def test_grid_map_free_servers_locking
      agridhub = WatirGrid::GridHub.new
      agridhub.load_server_config(@config_file_3)
      
      # Basic check before and after a get_server
      assert_equal(2 , agridhub.free_servers("ie6_xp")  , "Check number of free servers is correct before locking")
      hub_response = agridhub.get_server("ie6_xp")
      assert_equal(String.new.class , hub_response.class  , "Check String retured when 'get_server' is used")
      assert(YAML::load(hub_response).shift[1]["locked"]==true , "Check that status locked was returned")
      assert(YAML::load(hub_response).shift[1]["exists"]==true , "Check that status exists was returned")
      assert_equal(1 , agridhub.free_servers("ie6_xp")  , "Check number of free servers is correct/reduced after locking")
      assert_equal(1 , agridhub.free_servers("ie7_xp")  , "Check number of free servers is correct before locking")
      
     end # end test
    
     # Check locking returns false when 'get_server' called but no server available.
     #
     def test_grid_map_free_servers_locked
       agridhub = WatirGrid::GridHub.new
       agridhub.load_server_config(@config_file_3)
       
       # Get locks on only 2 servers.
       agridhub.get_server("ie6_xp")
       agridhub.get_server("ie6_xp")
       hub_response = agridhub.get_server("ie6_xp")
       assert(YAML::load(hub_response).shift[1]["exists"]==true , "Check that status exists was returned as true")
       assert(YAML::load(hub_response).shift[1]["locked"]==false , "Check that status unlocked was returned")
       
       hub_response = agridhub.get_server("ie7_xp")
       assert(YAML::load(hub_response).shift[1]["exists"]==true , "Check that status exists was returned as true")
       assert(YAML::load(hub_response).shift[1]["locked"]==true , "Check that status locked was returned")
    end # end test


    # Test lock and release
    #
    def test_grid_map_free_servers_lock_release
      agridhub = WatirGrid::GridHub.new
      agridhub.load_server_config(@config_file_3)
      
      # 1 matching server - unlocked.
      assert_equal( 1 , agridhub.free_servers("ie7_xp") , "lock release: Check that the server has not been locked")
      # Lock it...
      hub_response = agridhub.get_server("ie7_xp")
      locked_server_name = YAML::load(hub_response).shift[1]["name"]
      assert_equal( 0 , agridhub.free_servers("ie7_xp") , "lock release: Check that the server have been locked")
      
      hub_response = agridhub.release_server(locked_server_name)
      puts hub_response
      locked_server_exists = YAML::load(hub_response).shift[1]["exists"]
      assert_equal( true , locked_server_exists , "lock release: Check that the server exists")
      assert_equal( 1 , agridhub.free_servers("ie7_xp") , "lock release: Check that the server has been unlocked")
      
    end # test

  
    # Check locking returns exists false when 'get_server' called but no server with that key is in the pool.
    #
    def test_grid_map_free_servers_locked
      agridhub = WatirGrid::GridHub.new
      agridhub.load_server_config(@config_file_3)
      hub_response = agridhub.get_server("XXX_xp")
      assert(YAML::load(hub_response).shift[1]["exists"]==false , "Check that status exists was returned as false")
      assert(YAML::load(hub_response).shift[1]["locked"]==false , "Check that status locked was returned")
    end # end test

    
end # end class
